<?php
/**
 * JD_Pluggable 类
 *
 * 该类定义了与插件机制相关的方法：
 *   jd_add_action : 
 *   	供插件调用,调用时会将插件要执行的方法与JD系统提供的挂载点关联
 *	 jd_do_action :
 *   	供JD系统调用,调用时将执行插件的挂载方法
 *
 * @package 
 * @subpackage 
 * @category pluggable
 * @author tongliang
 * @link http://example.com
 */
class JD_Pluggable{
	var $actions ;
	var $filters ;
	function __construct() {
		$this->CI =& get_instance();
		$this->actions = array();
		$this->filters = array();
	}
	
	/**
	 * 
	 * 在插入点上添加插件函数
	 * 
	 * @param $tag	插入点标识
	 * @param $function 要执行的插件函数
	 * @return void
	 */
	function jd_add_action($tag,$function){
		$this->actions[$tag][]=$function;
	}
	
	/**
	 * 
	 * 执行与插入点相关的所有插件函数,按照添加的顺序执行  
	 * // TODO 加入优先级
	 * 
	 * @param $tag 插入点标识
	 * @param $arg 传入插件函数的参数
	 * @return void
	 */
	function jd_do_action($tag,$arg = ''){
		if ( ! array_key_exists($tag,$this->actions)){
			return ;
		}
		$actions = $this->actions[$tag];
		foreach ($actions as $func){
			$args = array();
			if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
				$args[] =& $arg[0];
			else
				$args[] = $arg;
			for ( $a = 2; $a < func_num_args(); $a++ ){
				$args[] = func_get_arg($a);
			}
			call_user_func_array($func,$args);
		}
		unset($this->actions[$tag]);
	}
	
	
	function jd_add_filter($tag,$funciton){
		$this->filters[$tag][]=$funciton;
	}
	
	/**
	 * 
	 * 执行与过滤点相关的所有过滤函数,按照添加的顺序执行  
	 * // TODO 加入优先级
	 * 
	 * @param $tag 过滤点标识
	 * @param $value 被过滤的内容
	 * @return mixed
	 */
	function jd_do_filter($tag,$value){
		if ( ! array_key_exists($tag,$this->filters)){
			return $value ;
		}
		$filters = $this->filters[$tag];
		foreach ($filters as $func){
			$args = array();
			for ( $a = 1; $a < func_num_args(); $a++ ){
				$args[] = func_get_arg($a);
			}
			$value = call_user_func_array($func,$args);
		}
		unset($this->filters[$tag]);
		return $value;
	}
}
?>